#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>

typedef struct {
    int argc;
    void* argv;
    void (*job_func)(int, void*);
} Job;

static void do_job(int argc, void* argv)
{
    int i = 5;
    printf("do_job: %d --> %s...\n", argc, (char*)argv);

    while (i-- > 0) {
        sleep(1);
    }
}

static Job g_job[] = {
    {1, "Delphi", do_job},
    {2, "D.T.Software", do_job},
    {3, "Tang", do_job},
};

static const int g_jlen = sizeof(g_job) / sizeof(*g_job);

static siginfo_t g_sig_arr[65] = {0};
static const int g_slen = sizeof(g_sig_arr) / sizeof(*g_sig_arr);

static void signal_handler(int sig, siginfo_t* info, void* ucontext)
{
    g_sig_arr[sig] = *info;
    g_sig_arr[0].si_signo++;
}

static void do_sig_process(siginfo_t* info)
{
    printf("do_sig_process: %d --> %d\n", info->si_signo, info->si_value.sival_int);
    
    // do process for the obj signal
    switch (info->si_signo) {
        case SIGINT:
            // call process function for SIGINT
            break;
        case 40:
            // call process function for 40
            break;
        default:
            break;
    }
}

static void process_signal()
{
    if (g_sig_arr[0].si_signo) {
        int i = 0;
        for (i = 1; i < g_slen; i++) {
            if (g_sig_arr[i].si_signo) {
                do_sig_process(&g_sig_arr[i]);

                g_sig_arr[i].si_signo = 0;
                g_sig_arr[0].si_signo--;
            }
        }
    }
}

static void app_init()
{
    struct sigaction act = {0};
    sigset_t set = {0};
    int i = 0;

    act.sa_sigaction = signal_handler;
    act.sa_flags = SA_RESTART | SA_SIGINFO;

    for (i = 1; i <= 64; i++) {
        sigaddset(&act.sa_mask, i);
    }

    for (i = 1; i <= 64; i++) {
        sigaction(i, &act, NULL);
    }
}

int main(int argc, char* argv[])
{
    int i = 0;
    
    printf("current pid(%d) ...\n", getpid());

    app_init();

    while (i < g_jlen) {
        int argc = g_job[i].argc;
        char* argv = g_job[i].argv;

        g_job[i].job_func(argc, argv);
        
        process_signal();

        i++;
    }

    return 0;
}
